

#include "ai_rts.h"

using namespace WtfEngine;
using namespace WtfEngine::AiModels::RtsUnit;

bool Idle::Evaluate(const IActor::tRef& rActor) {
	// Leave be?
	return true;
};

bool IntermediateMove::Evaluate(const IActor::tRef &rActor) {
	IMobileActor * pActor = dynamic_cast<IMobileActor *>(&*rActor);
	if(pActor) {
		return this->Evaluate(pActor, pActor->getGoalPosition());
	} else {
		throw new std::logic_error("Non-mobile actor trying to use intermediate move behaviour");
	};
};

bool IntermediateMove::Evaluate(const IMobileActor::tRef& rActor, const tPosition& vGoal) {
	tDirection vDesiredVelocity;

	if(!mrGoalMotion->Evaluate(rActor, vGoal, vDesiredVelocity))
		return false;
	return mrMotionControl->Evaluate(rActor, vDesiredVelocity);
};

bool Move::Evaluate(const IActor::tRef& rActor) {
	tPosition vIntermediateGoal;
	IMobileActor::tRef rMobileActor = dynamic_cast<IMobileActor *>(&*rActor);

	if(!rMobileActor.isNull()) {
		if(!mrPathfinding->Evaluate(rMobileActor, rMobileActor->getGoalPosition(), vIntermediateGoal))
			return false;
		return IntermediateMove::Evaluate(rMobileActor, vIntermediateGoal);
	} else {
		throw new std::logic_error("Non-mobile actor trying to use move behaviour");
	};
};


/**** Attack AiModel *****/

Attack::Attack(const WtfEngine::StringPool::Entry &sName, const WtfEngine::AiModel::tRef &rBaseAiModel):
Decorator(sName, rBaseAiModel) {
};


/**
 * An attacking unit will usually follow its target (if in range). This is achieved by
 * setting the base AI model to a movement model.
 **/
bool Attack::Evaluate(const IActor::tRef& rActor) {
	IRtsUnit * pUnit = dynamic_cast<IRtsUnit *>(&*rActor);
	IRtsUnit::tRef rTarget(pUnit->getTargetedUnit());
	
	if(pUnit) {
		pUnit->AttackUnit(rTarget);
		
		// TODO: move
		return Decorator::Evaluate(rActor);
	} else {
		throw new std::logic_error("Non-RtsUnit actor trying to use attack behaviour");
	};
};

